#include "concurrence.h"

#ifdef CDEV_DEBUGB
#define dbg_print(fmt, ...)			\
	do{								\
		printk("CDEV: ");			\
		printk(fmt, ##__VA_ARGS__);	\
		printk("\r\n");				\
	}while(0)
#else
#define dbg_print(fmt, ...)
#endif

#ifdef USING_ATOMIC
static atomic_t state;
#endif
#ifdef USING_SPINLOCK
static spinlock_t lock;
static int state;
#endif
#ifdef USING_SEM
static struct semaphore sem;
#endif
#ifdef USING_MUTEX
static struct mutex lock;
#endif

static int cdev_open(struct inode *inode, struct file *file)
{
#ifdef USING_ATOMIC
	if(!atomic_dec_and_test(&state))
	{
		atomic_set(&state, 0);
		return -EBUSY;
	}
#endif
#ifdef USING_SPINLOCK
	spin_lock(&lock);
	if(state != 1)
	{
		spin_unlock(&lock);
		return -EBUSY;
	}
	state = 0;
	spin_unlock(&lock);
#endif
#ifdef USING_SEM
	if(down_interruptible(&sem))
		return -ERESTARTSYS; 
#endif
#ifdef USING_MUTEX
	if(mutex_lock_interruptible(&lock))
		return -ERESTARTSYS; 
#endif
	return 0;
}

static int cdev_release(struct inode *inode, struct file *file)
{
#ifdef USING_ATOMIC
	atomic_set(&state, 1);
#endif
#ifdef USING_SPINLOCK
	spin_lock(&lock);
	state = 1;
	spin_unlock(&lock);
#endif
#ifdef USING_SEM
	up(&sem);
#endif
#ifdef USING_MUTEX
	mutex_unlock(&lock);
#endif
	return 0;
}


struct file_operations fops = {
	.owner = THIS_MODULE,
	.open = cdev_open,
	.release = cdev_release,
};
struct miscdevice misc;

static int register_cdev(void)
{
#ifdef USING_ATOMIC
	//设置原子变量
	atomic_set(&state, 1);
#endif
#ifdef USING_SPINLOCK
	state = 1;
	//初始化自旋锁
	spin_lock_init(&lock);
#endif
#ifdef USING_SEM
	//初始化信号量
	sema_init(&sem, 1);
#endif
#ifdef USING_MUTEX
	//初始化互斥量
	 mutex_init(&lock);
#endif
	//注册混杂设备
	misc.minor = CDEV_MINOR;
	misc.name = CDEV_NAME;
	misc.fops = &fops;
	return misc_register(&misc);
}

static void unregister_cdev(void)
{
	//注销混杂设备
	misc_deregister(&misc);
}

module_init(register_cdev);
module_exit(unregister_cdev);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("lf");
MODULE_DESCRIPTION("misc");
